/***************************************************************************************************/
/*!
 @header MovieToAudioExtractor
 @abstract   ￼Extract audio from QTMovie
 @discussion ￼
 This is the actual utility class that converts Movie in path into audio file and save it to
 toDir.
 
 Created by Hiroki Omae on 09/06/07.
 Copyright 2009 (c) Monkey Coders.
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 */
/***************************************************************************************************/

//-----------------------------------------------------------------------------------------------------------------------------
// File Dependencies
//-----------------------------------------------------------------------------------------------------------------------------
#import <Cocoa/Cocoa.h>
#import <QTKit/QTKit.h>
#import "AudioFileWriter.h"
#import "MovieToAudioExtractor.h"

//-----------------------------------------------------------------------------------------------------------------------------
// Private Interface.
//-----------------------------------------------------------------------------------------------------------------------------
@interface MovieToAudioExtractor (Private)
-(NSString*) _CreateOutputFilePath:(NSString*)path 
							   dir:(NSString*)dir
							  type:(NSString*)strType;
- (BOOL)_moveFileToTrash:(NSString *)filename;
@end
//-----------------------------------------------------------------------------------------------------------------------------
// Impl.
//-----------------------------------------------------------------------------------------------------------------------------
@implementation MovieToAudioExtractor

- (id) init
{
	self = [super init];
	if (self != nil) {
		mOutputFilePath = nil;
		mError = nil;
	}
	return self;
}


#pragma mark ---- private method ----
/*!
 @brief Create output path
 */
-(NSString*) _CreateOutputFilePath: (NSString*)path dir:(NSString*)dir 
{
	
	NSString *pStr = [[NSString alloc] initWithFormat:@"%@/%@.aiff", dir, [path lastPathComponent]];
	
	return pStr;
}

#pragma mark ---- public method ----
/*!
 @brief オブジェクト破棄
 */
- (void) dealloc
{
	if(mOutputFilePath) {
		[mOutputFilePath release];
	}
	if(mError) {
		[mError release];
	}
	[super dealloc];
}


/*!
 @abstract ムービーファイルからオーディオファイルを生成する
 @discussion
 入力のムービーファイルを開き、オーディオトラックを展開、別のファイルに
 保存して、新しく生成したファイルのパスを返します。
 
 @param [in]	path 	入力ファイルのパス
 @param [in]  dir 	出力ファイルの保存先
 */
- (void)extractAudioFromFile: (NSString*)path 
					   toDir:(NSString*)dir
				   deleteSrc:(BOOL)deleteSrc
{
	QTMovie 	*pMovie;
	AudioFileWriter 	*pAudioFileWriter;
	NSString	*pOutStr;
	NSError	*pErr = nil;
	
	if( mOutputFilePath ) {
		[mOutputFilePath release];
		mOutputFilePath = nil;
	}
	if( mError ) {
		[mError release];
		mError = nil;
	}
	
	/*
	 QTムービーのロードを非同期で読まないように指定
	 */
	NSDictionary *attrs = [NSDictionary dictionaryWithObjectsAndKeys:
						   (id)path, QTMovieFileNameAttribute,
						   [NSNumber numberWithBool:NO], QTMovieOpenAsyncOKAttribute,
						   nil];
	pMovie = [QTMovie movieWithAttributes:attrs error:&pErr];
	
	// ロード失敗
	if (pErr) {
		// error end. error detail is stored into "error" object.
		mError = pErr;
		[mError retain];
		return;
	}
	
	// オーディオトラックがない
	if (FALSE == [[pMovie attributeForKey:QTMovieHasAudioAttribute] boolValue]) {
		return;
	}
	
	pOutStr = [self _CreateOutputFilePath:path dir:dir];
	// 書き出し
	pAudioFileWriter = [[[AudioFileWriter alloc] init] autorelease];
	if ( noErr != [pAudioFileWriter exportAudioFileFromMovie:pMovie toFile:pOutStr error:&pErr] ) {
		// error end. error detail is stored into "error" object.
		mError = pErr;
		[mError retain];
		return;
	}
	
	// 書き出し成功して ソースを削除する場合、ここで削除
	if( pOutStr && deleteSrc ) {
		if( ![self _moveFileToTrash:path] ) {
			return;
		}
	}
	
	// コンバート結果のパスを保存
	mOutputFilePath = pOutStr;
}

/*!
 @abstract 	ムービーファイルからオーディオファイルを生成する(セレクタ実行用)
 @discussion
 データ出力はセレクタ経由で行われるので、引数はDictionaryにつめてあります。
 このメソッドは、Dictionaryの内容を展開して、実際の出力メソッドを実行します。
 */
- (void)extractAudioFromDictionary:
(NSDictionary*)args {
	
	NSString* 	path;
	NSString* 	dir;
	BOOL 		deleteSrc;
	
	path 		= [args objectForKey:@"path"];
	dir 		= [args objectForKey:@"dir"];
	deleteSrc 	= [[args objectForKey:@"deleteSrc"] boolValue];
	
	[self extractAudioFromFile:path toDir:dir deleteSrc:deleteSrc];
}

/*!
 @function
 @abstract   ファイルをゴミ箱に入れる
 @param   [in]  filename 削除するファイルのパス
 @result     削除できたかどうか
 @see 	http://aerial.st/tags/carbon
 */

- (BOOL)_moveFileToTrash:(NSString *)filename
{
	FSRef fileRef;
	
	// 対象の存在をチェック
	if(![[NSFileManager defaultManager] fileExistsAtPath:filename]) {
		mError = [NSError errorWithDomain:NSOSStatusErrorDomain code:fnfErr userInfo:nil];
		[mError retain];
		return NO;
	}
	
	const char *cPath = [filename fileSystemRepresentation];
	OSStatus result = FSPathMakeRef ((UInt8*)cPath, &fileRef, NULL);
	if (result != noErr) {
		mError = [NSError errorWithDomain:NSOSStatusErrorDomain code:result userInfo:nil];
		[mError retain];
		return NO;
	}
	
	result = FSMoveObjectToTrashSync(&fileRef, NULL,  kFSFileOperationDefaultOptions);
	if (result != noErr) {
		mError = [NSError errorWithDomain:NSOSStatusErrorDomain code:result userInfo:nil];
		[mError retain];
		return NO;
	}
	
	return YES;
}


/*!
 @abstract 出力ファイル
 */
-(NSString*)outputFilePath {
	return mOutputFilePath;
}

/*!
 @abstract エラー
 */
-(NSError*)error {
	return mError;
}

@end
